
package decoderstage

import chisel3.util._
import chisel3._
import decoderstage.EXTOpCode._
object EXTOpCode {
  val EXT_Width = 3.U.getWidth
  val EXT_Zero = 0.U(EXT_Width.W)
  val EXT_Sign = 1.U(EXT_Width.W)
  val EXT_Lui = 2.U(EXT_Width.W)
  val EXT_Shamt = 3.U(EXT_Width.W)
}

class Extender extends Module {
  val io = IO(new Bundle {
    val imm16 = Input(UInt(16.W))
    val opCode = Input(UInt(EXT_Width.W))
    val imm32 = Output(UInt(32.W))
  })
  val imm16 = io.imm16
  val zeroExt = Cat(0.U(16.W), imm16)
  val signExt = {
    val sign32 = Wire(SInt(32.W))
    sign32 := io.imm16.asSInt()
    sign32.asUInt()
  }
  val luiExt = Cat(imm16, 0.U(16.W))
  val shamtExt = Cat(0.U(27.W), imm16(10, 6))

  val opCode = io.opCode
  io.imm32 := MuxCase(0.U, Seq(
    (opCode === EXT_Zero) -> zeroExt,
    (opCode === EXT_Sign) -> signExt,
    (opCode === EXT_Lui) -> luiExt,
    (opCode === EXT_Shamt) -> shamtExt
  ))
}
